package btb.engine;

import com.esotericsoftware.minlog.Log;

import btb.engine.CDisplayTask;
import btb.net.CChatClientTask;
import btb.net.CMetaClientTask;
import btb.ui.CInputTask;
import btb.util.CLogger;

public class CMainClient extends ATask
{
	public CTaskMessenger mailbox;
	private CDisplayTask displayer;
	private CInputTask inputpoll;
	private CMetaClientTask metaclient;
	private CChatClientTask chatclient;
	
	public CMainClient()
	{
		super(CTaskMessenger.TASK_MAIN);
		this.mailbox = new CTaskMessenger();
	}
	
	@Override
	public void update()
	{
		if(displayer == null || metaclient == null)
		{
			CLogger.cond_error("engine", "Standard update loop failure: a task object is null.");
			return;
		}
		
		this.handleMail();
		
		// [Refactoring]: Move all this shit to handleMail, possible alter mailbox structure to resemble organized version of something like below.
		if(displayer.getGuiRequest() == CDisplayTask.GUI_CONNECTION_REQUEST)
		{
			boolean connectionSuccessful;
			
			if(!metaclient.isConnected())
			{	
				this.metaclient = new CMetaClientTask(this, CTaskMessenger.TASK_MCLIENT, this.mailbox);
				
				if(connectionSuccessful = this.metaclient.setUp())
				{
					this.metaclient.start();
				}
				else
				{
					if(this.metaclient.tearDown()) {
						this.metaclient.kill();
					}
					
					CLogger.cond_warn("engine", "Unable to create metaclient.");
				}
			}
			else
			{
				// [Note]: There's already a connection.
				connectionSuccessful = true;
			}
			displayer.handleConnectionResults(connectionSuccessful);
		}
		
		if(!chatclient.isConnected())
		{	
			this.chatclient = new CChatClientTask(this, CTaskMessenger.TASK_CCLIENT, this.mailbox);
			
			if(this.chatclient.setUp())
			{
				this.chatclient.start();
			}
			else
			{
				if(this.chatclient.tearDown())
				{
					this.chatclient.kill();
				}
			
				CLogger.cond_warn("engine", "Unable to create chatclient.");
			}
		}
		else
		{
			
		}
		
		if(metaclient.isConnected())
		{
			if(metaclient.getLoginStatus() == CMetaClientTask.LOGIN_NONE)
			{
				// nothing?
			}
			else if(metaclient.getLoginStatus() == CMetaClientTask.LOGIN_EXISTS)
			{
				// [Development]: Ongoing connection functionality goes here.
			}
			else if(metaclient.getLoginStatus() == CMetaClientTask.LOGIN_FAIL)
			{
				displayer.handleLoginResults(metaclient.getLoginStatus());
				metaclient.setLoginStatus(CMetaClientTask.LOGIN_NONE);
			}
			else if(metaclient.getLoginStatus() == CMetaClientTask.LOGIN_PASS)
			{
				displayer.handleLoginResults(metaclient.getLoginStatus());
				metaclient.setLoginStatus(CMetaClientTask.LOGIN_EXISTS);
			}
		}
		
		this.displayer.update();
		
		// [Development]: Other main thread functionality goes here.
	}
	
	@Override
	public void handleEvent(CEvent _event){
		
	}

	@Override
	public void handleDeath(){}
	
	public void run()
	{
		System.out.println("Main thread's run method has been called.");
			
		while(!this.die)
			this.update();
			
		System.out.println("Main client has been killed.");
		this.displayer.kill();
		this.inputpoll.kill();
		System.exit(0);
	}
	
	public static void main(String[] args)
	{
		CLogger logger = new CLogger();
		logger.toFile(false);
		
		Log.set(Log.LEVEL_DEBUG);
		Log.setLogger(logger);
		
		CMainClient mainClient = new CMainClient();
		
		mainClient.displayer 	= new CDisplayTask(mainClient, CTaskMessenger.TASK_DISPLAY, mainClient.mailbox);
		mainClient.inputpoll 	= new CInputTask(mainClient, CTaskMessenger.TASK_INPUT, mainClient.mailbox);
		mainClient.metaclient 	= new CMetaClientTask(mainClient, CTaskMessenger.TASK_MCLIENT, mainClient.mailbox);
			mainClient.metaclient.setFriendlyName("Ashigaru");
		mainClient.chatclient	= new CChatClientTask(mainClient, CTaskMessenger.TASK_CCLIENT, mainClient.mailbox);
				
		Thread inputThread = new Thread(mainClient.inputpoll);
		inputThread.start();
		
			// client startup used to be here
		
		
		// CDisplayTask object implements Runnable, but is not given its own thread. This is because OpenGL throws a fit if you try
		// to use its function calls outside of the main thread... or something. I don't fully understand the problem, but it's much
		// easier to just move the functionality of the display thread and the "main client" to the same thread (the initial one). 
		mainClient.run();
	}
}
